From e9b54a136b4a75a5fa58a78121e6182463454abb Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 29 Nov 2005 11:38:53 +0100 Subject: [PATCH] Fix a race condition for multi-thread qemu dma, where vmx linux guests show warning "dma interrupt lost" and dma becomes very slow. root cause: In the time between set ide irq and set dma status, if guest receive the irq and query the status, it will find the status is not ready and therefore treat it as pseudo interrupt. Change the order of set irq and set dma status fixes this issue. Signed-off-by: Ke Yu --- tools/ioemu/hw/ide.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/ioemu/hw/ide.c b/tools/ioemu/hw/ide.c index 71ad561154..7c012cebcb 100644 --- a/tools/ioemu/hw/ide.c +++ b/tools/ioemu/hw/ide.c @@ -669,6 +669,8 @@ static int ide_read_dma_cb(IDEState *s, } if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) { s->status = READY_STAT | SEEK_STAT; + s->bmdma->status &= ~BM_STATUS_DMAING; + s->bmdma->status |= BM_STATUS_INT; ide_set_irq(s); #ifdef DEBUG_IDE_ATAPI printf("dma status=0x%x\n", s->status); @@ -736,6 +738,8 @@ static int ide_write_dma_cb(IDEState *s, if (n == 0) { /* end of transfer */ s->status = READY_STAT | SEEK_STAT; + s->bmdma->status &= ~BM_STATUS_DMAING; + s->bmdma->status |= BM_STATUS_INT; ide_set_irq(s); return 0; } @@ -983,6 +987,8 @@ static int ide_atapi_cmd_read_dma_cb(IDEState *s, if (s->packet_transfer_size <= 0) { s->status = READY_STAT; s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; + s->bmdma->status &= ~BM_STATUS_DMAING; + s->bmdma->status |= BM_STATUS_INT; ide_set_irq(s); #ifdef DEBUG_IDE_ATAPI printf("dma status=0x%x\n", s->status); @@ -2065,8 +2071,6 @@ static void ide_dma_loop(BMDMAState *bm) } /* end of transfer */ the_end: - bm->status &= ~BM_STATUS_DMAING; - bm->status |= BM_STATUS_INT; bm->dma_cb = NULL; bm->ide_if = NULL; } -- 2.30.2